home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 6 / develop 6 code / TCP / NewsWatcher / NewsWatcher 2.0d15 source / source / scroll.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-27  |  10.0 KB  |  433 lines  |  [TEXT/KAHL]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     scroll.c
  4.  
  5.     This module handles text window scrolling.
  6.     
  7.     Portions copyright © 1990, Apple Computer.
  8.     Portions copyright © 1993, Northwestern University.
  9.  
  10. ----------------------------------------------------------------------------*/
  11.  
  12. #include <stdlib.h>
  13.  
  14. #include "glob.h"
  15. #include "draw.h"
  16. #include "scroll.h"
  17. #include "util.h"
  18.  
  19.  
  20. /*    MakeVScroller adds a vertical scroll bar to a textedit window */
  21.  
  22. void MakeVScroller (WindowPtr wind)
  23. {
  24.     TWindow **info;
  25.     Rect windowRect,vScrollRect;
  26.     
  27.     info = (TWindow**)GetWRefCon(wind);
  28.     windowRect = wind->portRect;
  29.     
  30.     SetRect(&vScrollRect,
  31.         windowRect.right-windowRect.left - 15,
  32.         (**info).panelHeight-1,
  33.         windowRect.right-windowRect.left+1,
  34.         windowRect.bottom-windowRect.top-14);
  35.     NewControl(wind,&vScrollRect,"\p",true,0,0,0,scrollBarProc,kVScroll);
  36. }
  37.  
  38.  
  39. /* MakeHScroller adds a horizontal scroll bar to a textedit window */
  40.  
  41. void MakeHScroller (WindowPtr wind, short max)
  42. {
  43.     Rect windowRect,hScrollRect;
  44.     
  45.     windowRect = wind->portRect;
  46.     
  47.     SetRect(&hScrollRect,kSectionMargin,(windowRect.bottom-windowRect.top - 15),
  48.             (windowRect.right-windowRect.left - 14),
  49.             (windowRect.bottom-windowRect.top + 1));
  50.     NewControl(wind,&hScrollRect,"\p",true,0,0,max,scrollBarProc,kHScroll);
  51. }
  52.  
  53.  
  54. ControlHandle HScrollCont (WindowPtr wind)
  55. {
  56.     ControlHandle theControl;
  57.     
  58.     theControl = ((WindowPeek)wind)->controlList;
  59.     
  60.     while (theControl != nil && GetCRefCon(theControl) != kHScroll) 
  61.         theControl = (**theControl).nextControl;
  62.     return theControl;
  63. }
  64.  
  65.  
  66. ControlHandle VScrollCont (WindowPtr wind)
  67. {
  68.     ControlHandle theControl;
  69.     
  70.     theControl = ((WindowPeek)wind)->controlList;
  71.     
  72.     while (theControl != nil && GetCRefCon(theControl) != kVScroll) 
  73.         theControl = (**theControl).nextControl;
  74.     return theControl;
  75. }
  76.  
  77.  
  78. static long sign (long longVar)
  79. {
  80.     if (longVar>=0)
  81.         return(1);
  82.     else
  83.         return(-1);
  84. }
  85.  
  86.  
  87. short LinesInText (TEHandle theTE)
  88. {
  89.     short lines;
  90.     Handle textHandle;
  91.     
  92.     lines = (**theTE).nLines;
  93.     textHandle = (**theTE).hText;
  94.     if ( (**theTE).teLength > 0 ) {
  95.         if ( *(*textHandle+((**theTE).teLength - 1)) == CR )
  96.             lines++;
  97.         return(lines);
  98.     }
  99. }
  100.  
  101.  
  102. void MoveText (WindowPtr wind, ControlHandle theControl)
  103. {
  104.     long    viewTop,destTop;
  105.     long    scrollValue;
  106.     long    scrollDiff,oldScroll,newScroll;
  107.     short    height;
  108.     TEHandle theTE;
  109.     TWindow **info;
  110.     Rect windowRect,r;
  111.     Handle text;
  112.     long **breaks;
  113.     long offset;
  114.     long length;
  115.     short curSection;
  116.     char *p, *pEnd;
  117.     
  118.     info = (TWindow**)GetWRefCon(wind);
  119.     theTE = (**info).theTE;    
  120.  
  121.     if (GetCRefCon(theControl) == kVScroll) {
  122.         viewTop = (**theTE).viewRect.top;
  123.         destTop = (**theTE).destRect.top;
  124.         oldScroll = viewTop - destTop;
  125.         scrollValue = GetCtlValue(theControl);
  126.         height = (**theTE).lineHeight;
  127.         newScroll = scrollValue * height;
  128.         scrollDiff = oldScroll - newScroll;
  129.         if (abs(scrollDiff)>32000) {
  130.             TEScroll(0,sign(scrollDiff) * 32000,theTE);
  131.             SysBeep(30);
  132.         } else if (scrollDiff != 0) {
  133.             TEScroll(0,scrollDiff,theTE);
  134.         }
  135.     } else {
  136.         curSection = GetCtlValue(theControl);
  137.         (**info).curSection = curSection;
  138.         SetPort(wind);
  139.         windowRect = wind->portRect;
  140.         SetRect(&r,kTextMargin,windowRect.bottom-13,kSectionMargin-2,
  141.             windowRect.bottom-2);
  142.         EraseRect(&r);
  143.         DrawSectionMessage(wind);
  144.         text = (**info).fullText;
  145.         HLock(text);
  146.         breaks = (**info).sectionBreaks;
  147.         offset = (*breaks)[(**info).curSection];
  148.         length = (*breaks)[(**info).curSection+1] - offset;
  149.         if (curSection == 0 && !(**info).headerShown) {
  150.             p = *text + offset;
  151.             pEnd = p + length;
  152.             while (p < pEnd) {
  153.                 if (*p == CR && *(p+1) == CR) break;
  154.                 p++;
  155.             }
  156.             p += 2;
  157.             while (p < pEnd && *p == CR) p++;
  158.             if (p < pEnd) {
  159.                 offset = p - *text;
  160.                 length = pEnd - p;
  161.             }
  162.         }
  163.         TESetText(*text+offset,length,theTE);
  164.         HUnlock(text);
  165.         TESetSelect(0,0,theTE);
  166.         AdjustScrollBar(wind);
  167.         SetCtlValue(VScrollCont(wind),0);
  168.         (**theTE).destRect = (**theTE).viewRect;
  169.         EraseRect(&(**theTE).destRect);
  170.         TEUpdate(&(**theTE).destRect,theTE);
  171.     }
  172. }
  173.  
  174.  
  175. void AdjustScrollBar (WindowPtr wind)
  176. {
  177.     short windowLines,currentLines;
  178.     TEHandle theTE;
  179.     TWindow **info;
  180.     
  181.     info = (TWindow**)GetWRefCon(wind);
  182.     theTE = (**info).theTE;    
  183.  
  184.     windowLines = ((**theTE).viewRect.bottom - (**theTE).viewRect.top) / 
  185.         (**theTE).lineHeight;
  186.     if ((currentLines = LinesInText(theTE)) > windowLines)
  187.         SetCtlMax(VScrollCont(wind),currentLines - windowLines);
  188.     else
  189.         SetCtlMax(VScrollCont(wind),0);
  190. }
  191.  
  192.  
  193. void ScrollChar (WindowPtr wind, short charPos, Boolean toBottom)
  194. {
  195.     short theLine, windowLines, nLines;
  196.     TEHandle theTE;
  197.     TWindow **info;
  198.     
  199.     info = (TWindow**)GetWRefCon(wind);
  200.     theTE = (**info).theTE;    
  201.     nLines = (**theTE).nLines;
  202.     
  203.     theLine = 0;
  204.     while (theLine < nLines && (**theTE).lineStarts[theLine + 1] <= charPos )
  205.         theLine++;
  206.     if (toBottom) {
  207.         windowLines = ((**theTE).viewRect.bottom - (**theTE).viewRect.top) / (**theTE).lineHeight;
  208.         theLine = theLine - (windowLines - 1);
  209.     }
  210.     SetCtlValue(VScrollCont(wind),theLine);
  211.     MoveText(wind,VScrollCont(wind));
  212. }
  213.  
  214.  
  215. void CheckInsertion (WindowPtr wind)
  216. {
  217.     short topLine,bottomLine,windowLines;
  218.     TEHandle theTE;
  219.     TWindow **info;
  220.     
  221.     info = (TWindow**)GetWRefCon(wind);
  222.     theTE = (**info).theTE;    
  223.     
  224.     windowLines = ((**theTE).viewRect.bottom - (**theTE).viewRect.top) / (**theTE).lineHeight;
  225.     topLine = GetCtlValue(VScrollCont(wind));
  226.     bottomLine = topLine + windowLines;
  227.     if (bottomLine > (**theTE).nLines) {
  228.         bottomLine = (**theTE).nLines;
  229.     }
  230.     if (GetCtlMax(VScrollCont(wind)) == 0)
  231.         MoveText(wind,VScrollCont(wind));
  232.     else if ((**theTE).selEnd < (**theTE).lineStarts[topLine])
  233.         ScrollChar(wind,(**theTE).selStart,false);
  234.     else if ((**theTE).selStart >= (**theTE).lineStarts[bottomLine])
  235.         ScrollChar(wind,(**theTE).selEnd,true);
  236. }
  237.  
  238.  
  239.  
  240. static pascal void scroll_action (ControlHandle scrollBar, short part)
  241. {
  242.     short    scrollAmt = 0,pageSize;
  243.     short    theCtlValue;
  244.     TEHandle theTE;
  245.     long refCon;
  246.     TWindow **info;
  247.     
  248.     info = (TWindow**)GetWRefCon(FrontWindow());
  249.     theTE = (**info).theTE;    
  250.     refCon = GetCRefCon(scrollBar);
  251.     
  252.     pageSize =  ((**theTE).viewRect.bottom - (**theTE).viewRect.top) / (**theTE).lineHeight - 1;
  253.     switch (part) {
  254.         case inUpButton:
  255.             scrollAmt = -1;
  256.             break;
  257.         case inDownButton:
  258.             scrollAmt = 1;
  259.             break;
  260.         case inPageUp:
  261.             scrollAmt = (refCon == kVScroll) ? -pageSize : -1;
  262.             break;
  263.         case inPageDown:
  264.             scrollAmt = (refCon == kVScroll) ? pageSize : 1;
  265.             break;
  266.     }
  267.     theCtlValue = GetCtlValue(scrollBar)+scrollAmt;
  268.     if (refCon == kVScroll && (part == inPageDown || part == inPageUp)
  269.         || theCtlValue <= GetCtlMax(scrollBar) && theCtlValue >= GetCtlMin(scrollBar))
  270.     {
  271.         SetCtlValue(scrollBar,GetCtlValue(scrollBar)+scrollAmt);
  272.         MoveText(FrontWindow(),scrollBar);
  273.     }
  274. }
  275.  
  276.  
  277. void DoScrollers (ControlHandle scrollBar, short part, Point localMouse)
  278. {
  279.     if (part == inThumb) {
  280.         TrackControl(scrollBar,localMouse,nil);
  281.         MoveText(FrontWindow(),scrollBar);
  282.     }
  283.     else
  284.         TrackControl(scrollBar,localMouse,(ProcPtr) scroll_action);
  285. }    
  286.  
  287.  
  288. pascal Boolean AutoScroll (void)
  289. {
  290.     RgnHandle    oldClip;
  291.     Point        mouseLoc;
  292.     Rect        textRect,tempRect;
  293.     short        deltaX = 0,deltaY = 0;
  294.     ControlHandle sBar;
  295.     TEHandle theTE;
  296.     TWindow **info;
  297.     
  298.     info = (TWindow**)GetWRefCon(FrontWindow());
  299.     theTE = (**info).theTE;    
  300.     
  301.     oldClip = NewRgn();
  302.     GetClip(oldClip);
  303.     tempRect = FrontWindow()->portRect;
  304.     ClipRect(&tempRect);
  305.     GetMouse(&mouseLoc);
  306.     textRect = (**theTE).viewRect;
  307.     if (mouseLoc.v < textRect.top)
  308.         deltaY = -1;
  309.     else if (mouseLoc.v > textRect.bottom)
  310.         deltaY = 1;
  311.     if (deltaY) {
  312.         sBar = VScrollCont(FrontWindow());
  313.         if (GetCtlValue(sBar)+deltaY <= GetCtlMax(sBar) &&
  314.             GetCtlValue(sBar)+deltaY >= GetCtlMin(sBar)) {
  315.             SetCtlValue(sBar,GetCtlValue(sBar)+deltaY);
  316.             MoveText(FrontWindow(),sBar);
  317.         }
  318.     }
  319.     SetClip(oldClip);
  320.     DisposeRgn(oldClip);
  321.     return true;
  322. }
  323.  
  324.  
  325. void ScrollTextLineUp (WindowPtr wind)
  326. {
  327.     ControlHandle scrollBar;
  328.     short newCtlValue;
  329.     
  330.     scrollBar = VScrollCont(wind);    
  331.     newCtlValue = GetCtlValue(scrollBar) - 1;
  332.     if (newCtlValue < 0) return;
  333.     SetCtlValue(scrollBar, newCtlValue);
  334.     MoveText(wind, scrollBar);
  335. }
  336.  
  337.  
  338. void ScrollTextLineDown (WindowPtr wind)
  339. {
  340.     ControlHandle scrollBar;
  341.     short newCtlValue;
  342.     
  343.     scrollBar = VScrollCont(wind);    
  344.     newCtlValue = GetCtlValue(scrollBar) + 1;
  345.     if (newCtlValue > GetCtlMax(scrollBar)) return;
  346.     SetCtlValue(scrollBar, newCtlValue);
  347.     MoveText(wind, scrollBar);
  348. }
  349.  
  350.  
  351. void ScrollTextPageUp (WindowPtr wind)
  352. {
  353.     TWindow **info;
  354.     TEHandle theTE;
  355.     ControlHandle scrollBar;
  356.     short    pageSize, newCtlValue;
  357.     
  358.     info = (TWindow**)GetWRefCon(wind);
  359.     theTE = (**info).theTE;
  360.     scrollBar = VScrollCont(wind);    
  361.     pageSize =  ((**theTE).viewRect.bottom - (**theTE).viewRect.top) / (**theTE).lineHeight - 1;
  362.     newCtlValue = GetCtlValue(scrollBar) - pageSize;
  363.     if (newCtlValue < 0) newCtlValue = 0;
  364.     SetCtlValue(scrollBar, newCtlValue);
  365.     MoveText(wind, scrollBar);
  366. }
  367.  
  368.  
  369. void ScrollTextPageDown (WindowPtr wind)
  370. {
  371.     TWindow **info;
  372.     TEHandle theTE;
  373.     ControlHandle scrollBar;
  374.     short    pageSize, newCtlValue, ctlMax;
  375.     
  376.     info = (TWindow**)GetWRefCon(wind);
  377.     theTE = (**info).theTE;
  378.     scrollBar = VScrollCont(wind);    
  379.     pageSize =  ((**theTE).viewRect.bottom - (**theTE).viewRect.top) / (**theTE).lineHeight - 1;
  380.     ctlMax = GetCtlMax(scrollBar);
  381.     newCtlValue = GetCtlValue(scrollBar) + pageSize;
  382.     if (newCtlValue > ctlMax) newCtlValue = ctlMax;
  383.     SetCtlValue(scrollBar, newCtlValue);
  384.     MoveText(wind, scrollBar);
  385. }
  386.  
  387.  
  388. void ScrollTextHome (WindowPtr wind)
  389. {
  390.     ControlHandle scrollBar;
  391.     
  392.     scrollBar = VScrollCont(wind);    
  393.     SetCtlValue(scrollBar, 0);
  394.     MoveText(wind, scrollBar);
  395. }
  396.  
  397.  
  398. void ScrollTextEnd (WindowPtr wind)
  399. {
  400.     ControlHandle scrollBar;
  401.     
  402.     scrollBar = VScrollCont(wind);    
  403.     SetCtlValue(scrollBar, GetCtlMax(scrollBar));
  404.     MoveText(wind, scrollBar);
  405. }
  406.  
  407.  
  408. void ScrollTextLeft (WindowPtr wind)
  409. {
  410.     ControlHandle scrollBar;
  411.     short newCtlValue;
  412.     
  413.     scrollBar = HScrollCont(wind);
  414.     if (scrollBar == nil) return;    
  415.     newCtlValue = GetCtlValue(scrollBar) - 1;
  416.     if (newCtlValue < 0) return;
  417.     SetCtlValue(scrollBar, newCtlValue);
  418.     MoveText(wind, scrollBar);
  419. }
  420.  
  421.  
  422. void ScrollTextRight (WindowPtr wind)
  423. {
  424.     ControlHandle scrollBar;
  425.     short newCtlValue;
  426.     
  427.     scrollBar = HScrollCont(wind);
  428.     if (scrollBar == nil) return;    
  429.     newCtlValue = GetCtlValue(scrollBar) + 1;
  430.     if (newCtlValue > GetCtlMax(scrollBar)) return;
  431.     SetCtlValue(scrollBar, newCtlValue);
  432.     MoveText(wind, scrollBar);
  433. }